package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.Time;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductFeignClient productFeignClient;

    //添加购物车
    @Override
    public void addToCart(Long skuId, String userId, Integer skuNum) {
        /*
        1.判断购物车是否有该商品
            如果有 则数量增加
            如果没有 则添加商品
            显示实时价格
        2.每次添加购物车，这个商品都默认被选中状态
        3.按照修改时间排序
        4.保存数据 -->redis
        */
        //谁的购物车
        String cartKey = getCartKey(userId);
        //hash key field
        CartInfo cartInfoExist = (CartInfo) this.redisTemplate.opsForHash().get(cartKey, skuId.toString());
        //判断是否存在
        if (cartInfoExist!=null){
            //有这个购物项  保证购物车商品数量不能大于200
            if (cartInfoExist.getSkuNum()+skuNum>200){
                cartInfoExist.setSkuNum(200);
            }else {
                cartInfoExist.setSkuNum(cartInfoExist.getSkuNum() + skuNum);
            }
             //显示实时价格
             cartInfoExist.setSkuPrice(productFeignClient.getSkuPrice(skuId));
             //设置选中状态  1表示选中 0表示未选中
             if (cartInfoExist.getIsChecked().intValue()==0){
                 cartInfoExist.setIsChecked(1);
             }
            //设置修改时间
             cartInfoExist.setUpdateTime(new Date());
        }else{
            cartInfoExist = new CartInfo();

            //根据skuId获取skuInfo
            SkuInfo skuInfo = this.productFeignClient.getSkuInfo(skuId);
            cartInfoExist.setSkuId(skuId);
            if (skuNum>200){
                cartInfoExist.setSkuNum(200);
            }else {
                cartInfoExist.setSkuNum(skuNum);
            }
            cartInfoExist.setUserId(userId);
            //实时价格
            cartInfoExist.setSkuPrice(productFeignClient.getSkuPrice(skuId));
            //加入购物车时的价格
            cartInfoExist.setCartPrice(productFeignClient.getSkuPrice(skuId));
            cartInfoExist.setSkuName(skuInfo.getSkuName());
            cartInfoExist.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfoExist.setCreateTime(new Date());
            cartInfoExist.setUpdateTime(new Date());
        }
        //存储到缓存
        this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfoExist);
    }

    //查看购物车信息
    @Override
    public List<CartInfo> getCartList(String userId, String userTempId) {
        //声明一个集合列表 (未登录的购物车)
        List<CartInfo> cartInfoNoLoginList = new ArrayList<>();
        //判断临时用户id不为空
        if (!StringUtils.isEmpty(userTempId)) {
            //获取key
            String cartKey = this.getCartKey(userTempId);
            //根据key获取未登录的购物车信息
            cartInfoNoLoginList = this.redisTemplate.opsForHash().values(cartKey);
            //判断用户是否登录
            if (StringUtils.isEmpty(userId)) {
                //根据修改时间 排序未登录的购物车
                if (!CollectionUtils.isEmpty(cartInfoNoLoginList)) {
                    cartInfoNoLoginList.sort((o1, o2) -> {
                        return DateUtil.truncatedCompareTo(o2.getUpdateTime(), o1.getUpdateTime(), Calendar.SECOND);
                    });
                }
                //返回未登录的购物车信息
                return cartInfoNoLoginList;
            }
        }
        //创建一个登录的 购物车集合
        List<CartInfo> cartInfoLoginList = new ArrayList<>();
        //判断用户id不为空
        if (!StringUtils.isEmpty(userId)) {
            //获取登陆的购物车的key  user:1:cart
            String cartKey = this.getCartKey(userId);
            //获取登陆后的购物车
            BoundHashOperations<String,String,CartInfo> boundHashOperations = this.redisTemplate.boundHashOps(cartKey);
            //判断未登录的购物车是否为空
            if (!CollectionUtils.isEmpty(cartInfoNoLoginList)){
                //遍历未登录的购物车集合
                cartInfoNoLoginList.forEach(cartInfoNoLogin -> {
                    //如果boundHashOperations里有cartInfoNoLogin.getSkuId()，返回true
                    if (boundHashOperations.hasKey(cartInfoNoLogin.getSkuId().toString())){
                        //获取登陆后购物车的商品信息(一个)
                        CartInfo cartInfoLogin = boundHashOperations.get(cartInfoNoLogin.getSkuId().toString());
                        //如果登陆后购物车商品数量+未登录购物车商品数量>200个
                        if (cartInfoLogin.getSkuNum()+cartInfoNoLogin.getSkuNum()>200){
                            cartInfoLogin.setSkuNum(200);
                        }else{
                            cartInfoLogin.setSkuNum(cartInfoLogin.getSkuNum()+cartInfoNoLogin.getSkuNum());
                        }
                        //选中状态 未登录状态
                        if (cartInfoNoLogin.getIsChecked().intValue()==1){
                            //登陆状态
                            if (cartInfoLogin.getIsChecked().intValue()==0){
                                cartInfoLogin.setIsChecked(1);
                            }
                        }
                        cartInfoLogin.setUpdateTime(new Date());
                        //写入redis
                        this.redisTemplate.boundHashOps(cartKey).put(cartInfoLogin.getSkuId().toString(),cartInfoLogin);
                    }else{

                        if (cartInfoNoLogin.getIsChecked().intValue()==1){
                            cartInfoNoLogin.setUserId(userId);
                            cartInfoNoLogin.setCreateTime(new Date());
                            cartInfoNoLogin.setUpdateTime(new Date());
                            this.redisTemplate.opsForHash().put(cartKey,cartInfoNoLogin.getSkuId().toString(),cartInfoNoLogin);
                        }
                    }
                });
                //删除临时购物车
                this.redisTemplate.delete(this.getCartKey(userTempId));
            }
            //查询所有
            cartInfoLoginList = boundHashOperations.values();
        }
        if (CollectionUtils.isEmpty(cartInfoLoginList)){
            return new ArrayList<>();
        }
        //排序 查看 按照更新时间排序 降序
        cartInfoLoginList.sort((o1,o2)->{
            return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
        });
        //返回数据
        return cartInfoLoginList;
//        if (!StringUtils.isEmpty(userId)){
//            String cartKey = this.getCartKey(userId);
//
//
//            cartInfoLoginList = this.redisTemplate.opsForHash().values(cartKey);
//            if (!StringUtils.isEmpty(userTempId)){
//                //合并购物车
//                cartInfoNoLoginList.forEach(cartInfoNoLogin -> {
//                });
//            }else{
//                //不合并购物车
//
//                //排序 查看 按照更新时间排序 降序
//                cartInfoLoginList.sort((o1,o2)->{
//                    return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
//                });
//                return cartInfoLoginList;
//            }
//        }
    }

    //选中状态
    @Override
    public void checkCart(Long skuId, String userId, Integer isChecked) {
        //获取key
        String cartKey = this.getCartKey(userId);

        CartInfo cartInfo = (CartInfo) this.redisTemplate.opsForHash().get(cartKey, skuId.toString());
        if (cartInfo!=null){
            cartInfo.setIsChecked(isChecked);
            cartInfo.setUpdateTime(new Date());
            this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfo);
        }
    }

    @Override
    public void deleteCart(Long skuId, String userId) {
        //获取key
        String cartKey = this.getCartKey(userId);
        //调用方法删除
        this.redisTemplate.opsForHash().delete(cartKey,skuId.toString());
    }

    //根据用户Id 查询购物车列表
    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        String cartKey = this.getCartKey(userId);
        List<CartInfo> cartInfoList = this.redisTemplate.opsForHash().values(cartKey);
        List<CartInfo> cartInfoCheckedList = cartInfoList.stream().filter(cartInfo -> {
            return cartInfo.getIsChecked().intValue() == 1;
        }).collect(Collectors.toList());
//        ArrayList<CartInfo> cartInfos = new ArrayList<>();
        //        cartInfoList.forEach(cartInfo -> {
//            if (cartInfo.getIsChecked().intValue()==1){
//                cartInfos.add(cartInfo);
//            }
//        });
        //返回选中的购物车集合
        return cartInfoCheckedList;
    }

    //反选购物车
    @Override
    public void allCheckCart(String userId, Integer isChecked) {
        //获取购物车的key
        String cartKey = this.getCartKey(userId);
        List<CartInfo> cartInfoList = this.redisTemplate.opsForHash().values(cartKey);
        //创建一个map集合
        HashMap<String, Object> hashMap = new HashMap<>();
        cartInfoList.forEach(cartInfo -> {
            cartInfo.setIsChecked(isChecked);
            //存入缓存
            //this.redisTemplate.opsForHash().put(cartKey,cartInfo.getSkuId().toString(),cartInfo);
            hashMap.put(cartInfo.getSkuId().toString(),cartInfo);
        });
        this.redisTemplate.opsForHash().putAll(cartKey,hashMap);
    }

    //清空购物车
    @Override
    public void clearCart(String userId) {
        //获取购物车的key
        String cartKey = this.getCartKey(userId);
        this.redisTemplate.delete(cartKey);
    }

    private String getCartKey(String userId) {
        String cartKey = RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        return cartKey;
    }
}
